#基本使用AutoTokenizer 自动分词器加载tokenizer
import torch
from transformers import AutoTokenizer
torch.cuda.empty_cache()

#加载与保存
sen = "弱小的我也有大梦想!"
# 从HuggingFace加载，输入模型名称，即可加载对于的分词器
tokenizer = AutoTokenizer.from_pretrained("uer/roberta-base-finetuned-dianping-chinese")
print(tokenizer)
# tokenizer 保存到本地
tokenizer.save_pretrained("./roberta_tokenizer")
# 从本地加载tokenizer
tokenizer = AutoTokenizer.from_pretrained("./roberta_tokenizer/")
print(tokenizer)
print("----------------------------------------1-------------------------------------------")
#句子分词
tokens = tokenizer.tokenize(sen)
print(tokens)
print("----------------------------------------2-------------------------------------------")
#查看词典
print(tokenizer.vocab)
print(tokenizer.vocab_size)
print("----------------------------------------3-------------------------------------------")
#索引转换
#将词序列转换为id序列
ids = tokenizer.convert_tokens_to_ids(tokens)
print(ids)
# 将id序列转换为token序列
tokens = tokenizer.convert_ids_to_tokens(ids)
print(tokens)
# 将token序列转换为string
str_sen = tokenizer.convert_tokens_to_string(tokens)
print(str_sen)
# 将字符串转换为id序列，又称之为编码
ids = tokenizer.encode(sen, add_special_tokens = True)
print(ids)
# 将id序列转换为字符串，又称之为解码
str_sen = tokenizer.decode(ids, skip_special_tokens = False)
print(str_sen)
print("--------------------------------------4---------------------------------------------")
#填充与截断
# 填充
ids = tokenizer.encode(sen, padding = "max_length", max_length = 15)
print(ids)
# 截断
ids = tokenizer.encode(sen, max_length = 5, truncation = True)
print(ids)
print("-----------------------------------5------------------------------------------------")
#快速调用方式
inputs = tokenizer.encode_plus(sen, padding = "max_length", max_length = 15)
print(inputs)
inputs = tokenizer(sen, padding = "max_length", max_length = 15)
print(inputs)
print("------------------------------------6-----------------------------------------------")
#处理batch数据
sens = ["弱小的我也有大梦想",
        "有梦想谁都了不起",
        "追逐梦想的心，比梦想本身，更可贵"]
res = tokenizer(sens)
print(res)
print("-------------------------------------7----------------------------------------------")
# 单条循环处理
for i in range(1000):
	tokenizer(sen)
# 处理batch数据(小技巧更快)
res = tokenizer([sen] * 1000)
print(res)
print("-------------------------------------8----------------------------------------------")
#Fast / Slow Tokenizer (fast基于Rust实现速度快,slow基于Python实现速度慢)
sen = "弱小的我也有大Dreaming!"
fast_tokenizer = AutoTokenizer.from_pretrained("uer/roberta-base-finetuned-dianping-chinese")
print(fast_tokenizer)
slow_tokenizer = AutoTokenizer.from_pretrained("uer/roberta-base-finetuned-dianping-chinese", use_fast = False)
print(slow_tokenizer)
inputs = fast_tokenizer(sen, return_offsets_mapping = True)
#return_offsets_mapping 获取每个token在原始文本中的位置返回字符串与token的映射关系
print(inputs)
print(inputs.word_ids())  #word_ids()word_ids()方法返回一个列表，列表中的每个元素对应input_ids中的每个token，# 表示该token属于哪个原始单词。
#如果某个token是独立的单词，则其对应的值为该单词的索引；如果是子词，则其对应的值与前一个token相同，表示它们属于同一个单词。
#如果某个token是特殊token（如[CLS]、[SEP]），则其对应的值为None。
print("---------------------------------------9--------------------------------------------")
#特殊Tokenizer的加载,trust_remote_code用于加载远程模型
#新版本的transformers（>4.34），加载 THUDM/chatglm 会报错，因此这里替换为了天宫的模型
tokenizer = AutoTokenizer.from_pretrained("Skywork/Skywork-o1-Open-PRM-Qwen-2.5-7B", trust_remote_code = True)
print(tokenizer)
tokenizer.save_pretrained("./roberta_tokenizer/")
tokenizer = AutoTokenizer.from_pretrained("skywork_tokenizer", trust_remote_code = True)
print(tokenizer.decode(tokenizer.encode(sen)))
print("----------------------------------------10-------------------------------------------")